package org.zachary.prosocialbehaviorservice.application;

import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zachary.prosocialbehaviorservice.application.command.ActivitiesDTO;
import org.zachary.prosocialbehaviorservice.application.command.ActivityDTO;
import org.zachary.prosocialbehaviorservice.application.command.AddActivityTypeCommand;
import org.zachary.prosocialbehaviorservice.application.command.ModifyActivityTypeCommand;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.Activity;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.ActivityItem;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.ActivityToItem;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.event.ActivityItemListEvent;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.event.DeleteActivityEvent;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.event.LoadAllActivityEvent;
import org.zachary.prosocialbehaviorservice.domain.repository.ActivityItemRepository;
import org.zachary.prosocialbehaviorservice.domain.repository.ActivityRepository;
import org.zachary.prosocialbehaviorservice.domain.repository.ActivityToItemRepository;
import org.zachary.prosocialbehaviorservice.infrastructure.utils.HiloGenerator;
import org.zachary.prosocialbehaviorservice.infrastructure.utils.UUIdUtil;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class ActivityService {

    private final ActivityRepository activityRepo;
    private final ActivityItemRepository itemRepo;
    private final ActivityToItemRepository mappingRepo;
    private final ApplicationEventPublisher eventPublisher;

    public ActivityService(ActivityRepository activityRepo,
                           ActivityItemRepository itemRepo,
                           ActivityToItemRepository mappingRepo,
                           HiloGenerator idGen, ApplicationEventPublisher eventPublisher) {
        this.activityRepo = activityRepo;
        this.itemRepo = itemRepo;
        this.mappingRepo = mappingRepo;
        this.eventPublisher = eventPublisher;
    }


    @Transactional
    public void addActivity(AddActivityTypeCommand command) {
        Activity activity=Activity.buildForAdd(
                command.title(),
                command.logo(),
                command.introduce(),
                command.content(),
                command.sponsor(),
                command.address()
        );
        activity.add();
        activityRepo.save(activity);
    }
    @Transactional
    public void deleteActivity(Integer id,String logo) {
            try {
                MinioClient minioClient = MinioClient.builder()
                        .endpoint("http://localhost:9000")
                        .credentials("admin","password123")
                        .build();
                // 提取对象名（即 key），从完整 URL 中解析出 bucket 内路径
                String bucket = "activity";

                // fileUrl: http://localhost:9000/activity/images/abc.png
                // objectName: images/abc.png
                String objectName = logo.replaceFirst(".*/" + bucket + "/", "");
                System.out.println();
                minioClient.removeObject(RemoveObjectArgs.builder()
                        .bucket(bucket)
                        .object(objectName)
                        .build());
            } catch (Exception e) {
                throw new RuntimeException("MinIO 文件删除失败", e);
            }
        Activity activity = activityRepo.findById(id).orElse(null);
        assert activity != null;
        activity.delete();
        activityRepo.deleteById(id);
        eventPublisher.publishEvent(new DeleteActivityEvent(activity));
    }
    @Transactional
    public void modifyActivity(Integer id, ModifyActivityTypeCommand command) {
        Activity activity = activityRepo.findById(id).orElse(null);
        assert activity != null;
        activity.setTitle(command.title());
        activity.setLogo(command.logo());
        activity.setIntroduce(command.introduce());
        activity.setContent(command.content());
        activity.setSponsor(command.sponsor());
        activity.setAddress(command.address());

        activity.modify();
        activityRepo.modify(id, activity);
    }
    @Transactional
    public ActivityDTO loadActivityWithItems(Integer id) {
        Activity activity = activityRepo.findById(id).orElse(null);
        assert activity != null;
        List<ActivityToItem> itemIds = mappingRepo.findByActivityId(activity.getId());
        List<ActivityItem> items = itemRepo.findAllById(itemIds);
        activity.loadItems(items);
        eventPublisher.publishEvent(new ActivityItemListEvent(activity));
        return ActivityDTO.from(activity);
    }
    @Transactional
    public List<ActivitiesDTO> loadAllActivities() {
        List<Activity> activities=activityRepo.findAllActivities();
        List<ActivitiesDTO> list= activities.stream().map(activity -> {
            ActivitiesDTO dto = new ActivitiesDTO(
                    activity.getId(),activity.getLogo(),
                    activity.getTitle(),activity.getIntroduce(),
                    activity.getContent(),activity.getSponsor(),activity.getAddress());

            return dto;
        }).collect(Collectors.toList());
        eventPublisher.publishEvent(new LoadAllActivityEvent(activities));
        return list;
    }

    public Optional<Activity> findById(Integer activityId) {
        return activityRepo.findById(activityId);
    }
}